// Copyright (C) 1953-2022 NUDT
// Verilog module name - controller_output_schedule
// Version: V3.4.0.20220301
// Created:
//         by - fenglin
////////////////////////////////////////////////////////////////////////////
// Description:
//         
///////////////////////////////////////////////////////////////////////////

`timescale 1ns/1ps

module controller_output_schedule
(
        i_clk              ,
        i_rst_n            ,
       
	    i_fifo_empty_1   ,
        o_fifo_rden_1    ,
        iv_fifo_rdata_1  ,
        
	    i_fifo_empty_2   ,
        o_fifo_rden_2    ,
        iv_fifo_rdata_2  ,

	    i_fifo_empty_3   ,
        o_fifo_rden_3    ,
        iv_fifo_rdata_3  ,          

	    i_fifo_empty_4   ,
        o_fifo_rden_4    ,
        iv_fifo_rdata_4  , 

	    i_fifo_empty_5   ,
        o_fifo_rden_5    ,
        iv_fifo_rdata_5  ,         

        ov_data            ,
        o_data_wr
); 
// I/O
// clk & rst
input                  i_clk            ;
input                  i_rst_n          ; 
// pkt input
input                  i_fifo_empty_1 ;
output reg      	   o_fifo_rden_1  ;
input	   [8:0] 	   iv_fifo_rdata_1;
                       
input                  i_fifo_empty_2 ;
output reg      	   o_fifo_rden_2  ;
input	   [8:0] 	   iv_fifo_rdata_2;
                       
input                  i_fifo_empty_3 ;
output reg      	   o_fifo_rden_3  ;
input	   [8:0] 	   iv_fifo_rdata_3;
                       
input                  i_fifo_empty_4 ;
output reg      	   o_fifo_rden_4  ;
input	   [8:0] 	   iv_fifo_rdata_4;

input                  i_fifo_empty_5 ;
output reg      	   o_fifo_rden_5  ;
input	   [8:0] 	   iv_fifo_rdata_5;

output reg [8:0]	   ov_data          ;
output reg	           o_data_wr        ;

//***************************************************
//               output schedule
//***************************************************
// internal reg&wire for state machine
reg  [3:0]  rv_cos_state;
//reg  [4:0]  rv_scheduled_record;//1:scheduled;0:not scheduled.
reg  [6:0]  rv_cycle_cnt;
localparam  IDLE_S         = 4'd0,
            SCHEDULE_DATA1_S = 4'd1,
            TRANSMIT_DATA1_S = 4'd2,
            SCHEDULE_DATA2_S = 4'd3,
            TRANSMIT_DATA2_S = 4'd4,
            SCHEDULE_DATA3_S = 4'd5,
            TRANSMIT_DATA3_S = 4'd6,
            SCHEDULE_DATA4_S = 4'd7,
            TRANSMIT_DATA4_S = 4'd8,
            SCHEDULE_DATA5_S = 4'd9,
            TRANSMIT_DATA5_S = 4'd10,
            CONTROL_GAP_S  = 4'd11;

always @(posedge i_clk or negedge i_rst_n) begin
    if(!i_rst_n) begin
        o_fifo_rden_1     <= 1'b0;                    
        o_fifo_rden_2     <= 1'b0;
        o_fifo_rden_3     <= 1'b0;
        o_fifo_rden_4     <= 1'b0;
        o_fifo_rden_5     <= 1'b0;
        ov_data             <= 9'b0;
        o_data_wr           <= 1'b0;
                         
        rv_cycle_cnt        <= 7'b0;
        //rv_scheduled_record <= 5'b0;
		rv_cos_state        <= IDLE_S;
    end
    else begin
		case(rv_cos_state)
			IDLE_S:begin 
                ov_data             <= 9'b0;
                o_data_wr           <= 1'b0; 
                rv_cycle_cnt        <= 7'b0;                
                if(!i_fifo_empty_1)begin
                    o_fifo_rden_1 <= 1'b1; 
                    rv_cos_state    <= SCHEDULE_DATA1_S; 
                end
                else if(!i_fifo_empty_2)begin
                    o_fifo_rden_2 <= 1'b1; 
                    rv_cos_state    <= SCHEDULE_DATA2_S; 
                end   
                else if(!i_fifo_empty_3)begin
                    o_fifo_rden_3 <= 1'b1; 
                    rv_cos_state    <= SCHEDULE_DATA3_S; 
                end
                else if(!i_fifo_empty_4)begin
                    o_fifo_rden_4 <= 1'b1; 
                    rv_cos_state    <= SCHEDULE_DATA4_S; 
                end
                else if(!i_fifo_empty_5)begin
                    o_fifo_rden_5 <= 1'b1; 
                    rv_cos_state    <= SCHEDULE_DATA5_S; 
                end                  
                else begin                  
                    o_fifo_rden_1     <= 1'b0;                    
                    o_fifo_rden_2     <= 1'b0;
                    o_fifo_rden_3     <= 1'b0;
                    o_fifo_rden_4     <= 1'b0;
                    o_fifo_rden_5     <= 1'b0;
                                     
                    rv_cos_state        <= IDLE_S;
                end                
            end            
            SCHEDULE_DATA1_S:begin
                ov_data      <= iv_fifo_rdata_1;
                o_data_wr    <= 1'b1;          
                rv_cos_state <= TRANSMIT_DATA1_S; 
            end
            TRANSMIT_DATA1_S:begin
                ov_data      <= iv_fifo_rdata_1;
                o_data_wr    <= 1'b1;          
                if(iv_fifo_rdata_1[8])begin//last cycle
                    o_fifo_rden_1     <= 1'b0; 
                    rv_cos_state        <= CONTROL_GAP_S;
                end
                else begin
                    rv_cos_state <= TRANSMIT_DATA1_S;
                end                
            end
            SCHEDULE_DATA2_S:begin
                ov_data      <= iv_fifo_rdata_2;
                o_data_wr    <= 1'b1;          
                rv_cos_state <= TRANSMIT_DATA2_S; 
            end
            TRANSMIT_DATA2_S:begin
                ov_data      <= iv_fifo_rdata_2;
                o_data_wr    <= 1'b1;          
                if(iv_fifo_rdata_2[8])begin//last cycle
                    o_fifo_rden_2  <= 1'b0;
                    rv_cos_state     <= CONTROL_GAP_S;
                end
                else begin
                    rv_cos_state <= TRANSMIT_DATA2_S;
                end                
            end
            SCHEDULE_DATA3_S:begin
                ov_data      <= iv_fifo_rdata_3;
                o_data_wr    <= 1'b1;          
                rv_cos_state <= TRANSMIT_DATA3_S; 
            end
            TRANSMIT_DATA3_S:begin
                ov_data      <= iv_fifo_rdata_3;
                o_data_wr    <= 1'b1;          
                if(iv_fifo_rdata_3[8])begin//last cycle
                    o_fifo_rden_3     <= 1'b0;
                    rv_cos_state        <= CONTROL_GAP_S;
                end
                else begin
                    rv_cos_state <= TRANSMIT_DATA3_S;
                end                
            end
            SCHEDULE_DATA4_S:begin
                ov_data      <= iv_fifo_rdata_4;
                o_data_wr    <= 1'b1;          
                rv_cos_state <= TRANSMIT_DATA4_S; 
            end
            TRANSMIT_DATA4_S:begin
                ov_data      <= iv_fifo_rdata_4;
                o_data_wr    <= 1'b1;          
                if(iv_fifo_rdata_4[8])begin//last cycle
                    o_fifo_rden_4     <= 1'b0;
                    rv_cos_state        <= CONTROL_GAP_S;
                end
                else begin
                    rv_cos_state <= TRANSMIT_DATA4_S;
                end                
            end
            SCHEDULE_DATA5_S:begin
                ov_data      <= iv_fifo_rdata_5;
                o_data_wr    <= 1'b1;          
                rv_cos_state <= TRANSMIT_DATA5_S; 
            end
            TRANSMIT_DATA5_S:begin
                ov_data      <= iv_fifo_rdata_5;
                o_data_wr    <= 1'b1;          
                if(iv_fifo_rdata_5[8])begin//last cycle
                    o_fifo_rden_5     <= 1'b0;
                    rv_cos_state        <= CONTROL_GAP_S;
                end
                else begin
                    rv_cos_state <= TRANSMIT_DATA5_S;
                end                
            end            
            CONTROL_GAP_S:begin
                rv_cycle_cnt <= rv_cycle_cnt + 1'b1;
                ov_data      <= 9'b0;
                o_data_wr    <= 1'b0;                
                if(rv_cycle_cnt == 7'd22)begin
                    rv_cos_state <= IDLE_S;	                
                end
                else begin
                    rv_cos_state <= CONTROL_GAP_S;	     
                end
            end            
			default:begin               
                ov_data      <= 9'b0;
                o_data_wr    <= 1'b0;                
                rv_cos_state <= IDLE_S;	
			end
		endcase
    end
end	
endmodule